#pragma once
namespace graph_virtual
{
   namespace details
   {

   }
  
struct virtual_view_vertex_iterator_t: std::forward_iterator_tag
{
   void operator ++ ();
   graph_basic::vertex_t& operator * ();
   graph_basic::vertex_t const & operator * () const;
   bool is_empty() const;
private:
   virtual_view_vertex_iterator_t(virtual_graph_view_ptr_t view);
   virtual_vertex_iterator_t it_;
   virtual_graph_view_ptr_t view_;
   friend virtual_view_vertex_iterator_t vertices(virtual_graph_view_ptr_t view);
};

struct virtual_view_edge_iterator_t: std::forward_iterator_tag
{
   void operator ++ ();
   graph_basic::edge_t operator * ();
   graph_basic::edge_t const operator * () const;
   bool is_empty() const;
private:
   virtual_view_edge_iterator_t(virtual_graph_view_ptr_t view);
   virtual_edge_iterator_t edge_it_;
   virtual_graph_view_ptr_t view_;
   friend virtual_view_edge_iterator_t edges(virtual_graph_view_ptr_t view);
};

struct virtual_view_adjacent_edges_iterator_t: std::forward_iterator_tag
{ 
    void operator ++ ();
    graph_basic::edge_t operator * ();
    graph_basic::edge_t const operator * () const;
    bool is_empty() const;
private:
   virtual_view_adjacent_edges_iterator_t(graph_basic::vertex_id_t source_v_id, virtual_graph_view_ptr_t view);
   virtual_adjacent_edges_iterator_t it_;
   virtual_graph_view_ptr_t view_;
   friend virtual_view_adjacent_edges_iterator_t adjacent_edges(graph_basic::vertex_id_t souce_v_id, virtual_graph_view_ptr_t view);
   friend struct virtual_view_adjacent_vertices_iterator_t;
};

struct virtual_view_adjacent_vertices_iterator_t: std::forward_iterator_tag
{
   void operator ++ ();
   graph_basic::vertex_t& operator * ();
   graph_basic::vertex_t const & operator * () const;
   bool is_empty() const;
private:
   virtual_view_adjacent_vertices_iterator_t(virtual_view_adjacent_edges_iterator_t it);
   virtual_view_adjacent_edges_iterator_t it_;
   friend virtual_view_adjacent_vertices_iterator_t adjacent_vertices(graph_basic::vertex_id_t souce_v_id, virtual_graph_view_ptr_t view);
};


inline virtual_view_vertex_iterator_t vertices(virtual_graph_view_ptr_t view);
inline virtual_view_edge_iterator_t edges(virtual_graph_view_ptr_t view);
inline virtual_view_adjacent_edges_iterator_t adjacent_edges(graph_basic::vertex_id_t souce_v_id, virtual_graph_view_ptr_t view);
inline virtual_view_adjacent_vertices_iterator_t adjacent_vertices(graph_basic::vertex_id_t souce_v_id, virtual_graph_view_ptr_t view);

template<>
struct graph_traits<virtual_graph_view_t>
{
   typedef virtual_view_vertex_iterator_t vertex_iterator;
   typedef virtual_view_edge_iterator_t edge_iterator;
   typedef virtual_view_adjacent_vertices_iterator_t adj_vertices_iterator;
   typedef virtual_view_adjacent_edges_iterator_t adj_edges_iterator;
};
}